package org.javahispano.javacup.tacticas_aceptadas.TanoRojas.tano;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import org.javahispano.javacup.modelo.Comando;
import org.javahispano.javacup.modelo.ComandoGolpearBalon;
import org.javahispano.javacup.modelo.ComandoIrA;
import org.javahispano.javacup.modelo.Constantes;
import org.javahispano.javacup.modelo.Posicion;
import org.javahispano.javacup.modelo.SituacionPartido;
import org.javahispano.javacup.modelo.Tactica;
import org.javahispano.javacup.modelo.TacticaDetalle;

/**
 * 
 * @author Lisandro Ra�l Rojas
 *
 * Pero que feo c�digo... pero bue, es lo que sali�... otro d�a lo limpio un poco :D
 */



public class Fulbots implements Tactica {

	FulbotsDetalle detalle = new FulbotsDetalle();
	private int irAAlineacion = 0;
	private int golesPropios = 0;
	private int golesRival = 0;

    private boolean marcado = false;
	private Posicion inicioPase = null;
	private int iteracionPase = 0;
	private int jugadorRecibePase = -1; 
	private Posicion posicionRecibePase;
	private boolean cambioDireccion;
	private double dx, dy;
	
	private int[] marcasJugador;
	
	private Posicion balonAnt, balon;

	private SituacionPartido sp;
    private Utils util;
    
    
        Posicion alineacion1[]=new Posicion[]{
            new Posicion(0.2595419847328244,-50.41044776119403),
            new Posicion(-19.734265734265733,-35.63348416289593),
            new Posicion(-0.23776223776223776,-35.15837104072398),
            new Posicion(19.97202797202797,-35.8710407239819),
            new Posicion(-13.314685314685315,-22.56787330316742),
            new Posicion(-0.4755244755244755,-23.042986425339365),
            new Posicion(12.125874125874127,-22.56787330316742),
            new Posicion(-22.825174825174827,-1.1877828054298643),
            new Posicion(0.951048951048951,-0.23755656108597287),
            new Posicion(8.55944055944056,-7.839366515837104),
            new Posicion(23.3006993006993,-0.7126696832579186)
        };

        Posicion alineacion2[]=new Posicion[]{
            new Posicion(0.2595419847328244,-50.41044776119403),
            new Posicion(-20.20979020979021,-35.39592760180996),
            new Posicion(0.0,-36.34615384615385),
            new Posicion(20.20979020979021,-36.10859728506787),
            new Posicion(-14.74125874125874,-23.042986425339365),
            new Posicion(0.0,-23.518099547511312),
            new Posicion(19.734265734265733,-23.518099547511312),
            new Posicion(-24.48951048951049,-1.4253393665158371),
            new Posicion(-7.846153846153847,-8.076923076923077),
            new Posicion(6.895104895104895,-8.789592760180994),
            new Posicion(24.727272727272727,-1.900452488687783)
        };

        Posicion alineacion3[]=new Posicion[]{
                new Posicion(0.2595419847328244,-50.41044776119403),
                new Posicion(-19.46564885496183,-31.6044776119403),
                new Posicion(0.2595419847328244,-31.082089552238806),
                new Posicion(19.984732824427482,-31.6044776119403),
                new Posicion(-21.874125874125873,5.701357466063349),
                new Posicion(-1.188811188811189,-10.690045248868778),
                new Posicion(23.776223776223777,6.176470588235294),
                new Posicion(-22.825174825174827,43.710407239819006),
                new Posicion(-0.7132867132867133,38.24660633484163),
                new Posicion(-1.188811188811189,18.054298642533936),
                new Posicion(22.825174825174827,43.23529411764706)
            };
        
    
        Posicion alineacionAtaque[]=new Posicion[]{
                new Posicion(0.2595419847328244,-50.41044776119403),
                new Posicion(-19.46564885496183,-31.6044776119403),
                new Posicion(0.2595419847328244,-31.082089552238806),
                new Posicion(19.984732824427482,-31.6044776119403),
                new Posicion(-21.874125874125873,5.701357466063349),
                new Posicion(-1.188811188811189,-10.690045248868778),
                new Posicion(23.776223776223777,6.176470588235294),
                new Posicion(-22.825174825174827,43.710407239819006),
                new Posicion(-0.7132867132867133,38.24660633484163),
                new Posicion(-1.188811188811189,18.054298642533936),
                new Posicion(22.825174825174827,43.23529411764706)
            };
    
    
//        Posicion alineacionDefensa[]=new Posicion[]{
//                new Posicion(0.2595419847328244,-50.41044776119403),
//                new Posicion(-26.62937062937063,-43.23529411764706),
//                new Posicion(-0.7132867132867133,-42.28506787330317),
//                new Posicion(24.48951048951049,-47.51131221719457),
//                new Posicion(-14.265734265734267,-34.44570135746606),
//                new Posicion(0.0,-23.518099547511312),
//                new Posicion(12.601398601398602,-35.63348416289593),
//                new Posicion(-27.34265734265734,-12.352941176470589),
//                new Posicion(-2.13986013986014,15.15837104072398),
//                new Posicion(0.23776223776223776,-5.701357466063349),
//                new Posicion(26.391608391608393,-11.64027149321267)
//            };  
        Posicion alineacionDefensa[]=new Posicion[]{
                new Posicion(0.2595419847328244,-50.41044776119403),
                new Posicion(-19.46564885496183,-31.6044776119403),
                new Posicion(0.2595419847328244,-31.082089552238806),
                new Posicion(19.984732824427482,-31.6044776119403),
                new Posicion(-21.874125874125873,5.701357466063349),
                new Posicion(-1.188811188811189,-10.690045248868778),
                new Posicion(23.776223776223777,6.176470588235294),
                new Posicion(-22.825174825174827,43.710407239819006),
                new Posicion(-0.7132867132867133,38.24660633484163),
                new Posicion(-1.188811188811189,18.054298642533936),
                new Posicion(22.825174825174827,43.23529411764706)
            };        

   
        
        Posicion alineacionAtaqueAdelantado[]=new Posicion[]{
                new Posicion(0.2595419847328244,-50.41044776119403),
                new Posicion(-18.78321678321678,-17.816742081447966),
                new Posicion(-1.6643356643356644,0.23755656108597287),
                new Posicion(18.545454545454543,-18.054298642533936),
                new Posicion(-12.125874125874127,28.744343891402718),
                new Posicion(-0.7132867132867133,24.468325791855204),
                new Posicion(13.552447552447552,29.21945701357466),
                new Posicion(-23.3006993006993,48.223981900452486),
                new Posicion(8.083916083916083,42.76018099547511),
                new Posicion(-1.6643356643356644,45.61085972850679),
                new Posicion(15.216783216783217,46.79864253393666)
            };
        

    Jugador jugador1 = new Jugador(1, alineacion3, new int[]{2,3,4});
    Jugador jugador2 = new Jugador(2, alineacion3, new int[]{3,5});
    Jugador jugador3 = new Jugador(3, alineacion3, new int[]{2,4,6});
    Jugador jugador4 = new Jugador(4, alineacion3, new int[]{3,7});
    Jugador jugador5 = new Jugador(5, alineacion3, new int[]{2,6,8,9});
    Jugador jugador6 = new Jugador(6, alineacion3, new int[]{3,5,7,9,10});
    Jugador jugador7 = new Jugador(7, alineacion3, new int[]{4,6,10,11});
    Jugador jugador8 = new Jugador(8, alineacion3, new int[]{5,9});
    Jugador jugador9 = new Jugador(9, alineacion3, new int[]{8,10});
    Jugador jugador10 = new Jugador(10, alineacion3, new int[]{9,11});
    Jugador jugador11 = new Jugador(11, alineacion3, new int[]{10,9});
    
      
    public Fulbots() {
    	util = new Utils();
    	util.setAlineacion(alineacion3);
    	marcasJugador = new int[11];
    	
    	balon = new Posicion(0,0);
    	balonAnt = new Posicion(0,0);
    	
    	dx = 0; dy = 0;
    	cambioDireccion = false;
    }

    public TacticaDetalle getDetalle() {
        return detalle;
    }
    int cambia = 0;

    public Posicion[] getPosicionSaca(SituacionPartido sp) {
        return alineacion1;
    }

    public Posicion[] getPosicionRecive(SituacionPartido sp) {
        return alineacion2;
    }
    
   
    Random rand = new Random();
    LinkedList<Comando> comandos = new LinkedList<Comando>();

    public List<Comando> ejecutar(SituacionPartido sp){
        comandos.clear();
        util.setSituacionPartido(sp);
        this.sp = sp;
        
        if (sp.golesPropios()!=golesPropios || sp.golesRival()!= golesRival) {
        	irAAlineacion = 0;
        	golesPropios = sp.golesPropios();
        	golesRival = sp.golesRival();
        }
        irAAlineacion++;
        
        Arrays.fill(marcasJugador, 0);
        int[] cercanos = Constantes.centroArcoInf.indicesMasCercanos(sp.rivales());
       marcasJugador[1] = cercanos[0];
       marcasJugador[2] = cercanos[1];
       marcasJugador[3] = cercanos[2];
       marcasJugador[4] = cercanos[3];
       marcasJugador[5] = cercanos[4];
       marcasJugador[6] = cercanos[5];
       marcasJugador[7] = cercanos[6];
       marcasJugador[8] = cercanos[7];
       marcasJugador[9] = cercanos[8];

       balonAnt = balon;
       balon = new Posicion(sp.balon().getX() , sp.balon().getY());
        
        if (sp.sacaRival() || (sp.puedenRematarRival().length>0 && sp.puedenRematar().length==0)) {
    	   cambioDireccion = true;
        }

        Comando[] comando = null;        
        
        comando = jugador1.getJugada();
        if (comando[0]!=null) {
        	comandos.add(comando[0]);
        	if (comando[1]!=null) comandos.add(comando[1]);
        }
        
        comando = jugador2.getJugada();
        if (comando[0]!=null) {
        	comandos.add(comando[0]);
        	if (comando[1]!=null) comandos.add(comando[1]);
        }
        
        comando = jugador3.getJugada();
        if (comando[0]!=null) {
        	comandos.add(comando[0]);
        	if (comando[1]!=null) comandos.add(comando[1]);
        }
        
        comando = jugador4.getJugada();
        if (comando[0]!=null) {
        	comandos.add(comando[0]);
        	if (comando[1]!=null) comandos.add(comando[1]);
        }

        
        comando = jugador5.getJugada();
        if (comando[0]!=null) {
        	comandos.add(comando[0]);
        	if (comando[1]!=null) comandos.add(comando[1]);
        }

        
        comando = jugador6.getJugada();        
        if (comando[0]!=null) {
        	comandos.add(comando[0]);
        	if (comando[1]!=null) comandos.add(comando[1]);
        }

        
        comando = jugador7.getJugada();
        if (comando[0]!=null) {
        	comandos.add(comando[0]);
        	if (comando[1]!=null) comandos.add(comando[1]);
        }

        
        comando = jugador8.getJugada();
        if (comando[0]!=null) {
        	comandos.add(comando[0]);
        	if (comando[1]!=null) comandos.add(comando[1]);
        }

        
        comando = jugador9.getJugada();
        if (comando[0]!=null) {
        	comandos.add(comando[0]);
        	if (comando[1]!=null) comandos.add(comando[1]);
        }

        
        comando = jugador10.getJugada();
        if (comando[0]!=null) {
        	comandos.add(comando[0]);
        	if (comando[1]!=null) comandos.add(comando[1]);
        }

        
        comando = jugador11.getJugada();
        if (comando[0]!=null) {
        	comandos.add(comando[0]);
        	if (comando[1]!=null) comandos.add(comando[1]);
        }
        
       // if (comandos.size()>0) {
       // 	System.out.println(comandos);
       // }

        return comandos;
    }
    
    
    private class Jugador {
    	
        private final int N;
    	private Posicion[] alineacion;
    	private int[] jugadoresPase;
    	
   	

    	//-----------------------------------------------------------------------------------------------------------------
    	public Jugador(int numJugador, Posicion[] paramAlin, int[] paramjugadoresPase) {
    		N = numJugador;
    		alineacion = paramAlin;
    		jugadoresPase = paramjugadoresPase; //new int[]{1,2,3,4,5,6,7,8,9,10,11};
    	}
    	
    	
    	
        //-----------------------------------------------------------------------------------------------------------------	
    	public Comando[] getJugada() {    		
    		Comando[] comando = new Comando[2];
    		comando[0] = null; comando[1] = null;
           

    		if (jugadorRecibePase==N) {
    			if (util.puedoRematar(N)) {
    				iteracionPase = -1;
    				cambioDireccion = true;
    			}
    			//System.out.println("itpase: "+iteracionPase + "   itact: " + sp.iteracion());
    				
    			if (iteracionPase!=sp.iteracion() || true) {
	    			if ((iteracionPase+1)==sp.iteracion()) {
	    				cambioDireccion = false;
	    				
	    				if (marcado) {
	    					posicionRecibePase = new Posicion(sp.balon().getX(), sp.balon().getY());
	    				}
	    				else {
	    					posicionRecibePase = mejorPosicionRecibirPase();	    					
	    			    }
    				    
	    				
	    				//System.out.println(sp.iteracion()+"|   JugRec: "+N);
	    				//System.out.println("Act: "+sp.misJugadores()[N-1]);
	    				//System.out.println("Mej: "+posicionRecibePase);
	    				//System.out.println();
	    				
	    				comando[0] =  new ComandoIrA(N-1, posicionRecibePase);
	    			}
	    			else
	    			if (!cambioDireccion) {
	    				//System.out.println(N+"->"+"Act: "+sp.misJugadores()[N-1]);
	    				//System.out.println(N+"->"+"Mej: "+posicionRecibePase);
	    				//System.out.println("Balon: "+sp.balon() + " - Marcado:" + marcado);
	    				//System.out.println("Jugador recibe:" + jugadorRecibePase);
	    				
	    				if (marcado) {
	    					comando[0] =  new ComandoIrA(N-1, sp.balon());
	    				}
	    				else {
	    					comando[0] =  new ComandoIrA(N-1, posicionRecibePase);
	    				}
	    				
	    			}
	    			else {
	    				jugadorRecibePase = -1;
	    				marcado = false;
	    			}    			
    			}
    			
    		}
    			
    		if (comando[0]==null) {
    			comando = this.rematar();
    		}
    		if (comando[0]==null) {
    			comando = this.gambetear(false);
    		}
	    	if (comando[0]==null) {
	    		comando = this.darPase();
	    	}
	    	if (comando[0]==null) {
	    		comando = this.moverse();
	    	}
    		
    		return comando;
    	}
    	
    	
    	//-----------------------------------------------------------------------------------------------------------------
    	public Posicion mejorPosicionRecibirPase() {
    		Posicion miPos = sp.misJugadores()[N-1];
    		Posicion posicionPase = null;
    		Posicion p = sp.balon();
    		dx = sp.balon().getX() - inicioPase.getX(); 
    		dy = sp.balon().getY() - inicioPase.getY();
    		
    		double distMin = Double.MAX_VALUE;
    		for(int iter=0; iter<50; iter++) {
                dx = dx * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
                dy = dy * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
                //System.out.println(iter+"->" + p.distancia(p.moverPosicion(dx, dy)));
                
    			p = p.moverPosicion(dx, dy);
    			
    			
    			double dist = p.distancia(miPos);
    			if (dist<distMin) {
    				distMin = dist;
    				posicionPase = p;
    			}
    		}
    		
    		return posicionPase;
    	}

    	
    	//-----------------------------------------------------------------------------------------------------------------
    	public Comando[] gambetear(boolean forzado) {
    		Comando[] comando = new Comando[2];
    		comando[0] = null; comando[1] = null;
    		
    		if (N!=1 && util.puedoRematar(N) && !sp.saco()) {
    			Posicion miPos = sp.balon();//sp.misJugadores()[N-1] ;
    			
    			Posicion posEnemigo = null;
    			double minDistEnemigo = Double.MAX_VALUE;
    			for (Posicion p : sp.rivales())
    				if (p.getY()>miPos.getY()-2 && miPos.distancia(p)<minDistEnemigo) {
    			       posEnemigo = new Posicion(p.getX(), p.getY());    			
    				}
    			
    			if (posEnemigo==null) {
    				posEnemigo = sp.rivales()[miPos.indiceMasCercano(sp.rivales())];
    			}
    			if (miPos.distancia(posEnemigo)<3) {
    				return comando;
    			}
    			   
    			if (!forzado) {
    				double xi = miPos.getX()-7; double xf = miPos.getX()+7;
    				double yi = miPos.getY()-3; double yf = miPos.getY()+15;
    				
    				boolean enemigosCerca = false;
    				for(Posicion p : sp.rivales()) {
    					if (xi<=p.getX() && p.getX()<=xf && yi<=p.getY() && p.getY()<=yf) {
    						enemigosCerca = true;
    					}
    				}
    				
    				if (enemigosCerca) {
    					return comando;
    				}
    			}
    			
    			double distMinima = 3.5;
    			if (forzado) {
    				distMinima = 0.6;
    				//System.out.println("Distancia: " + (miPos.distancia(sp.misJugadores()[N-1])));
    			}
    			
    			//Pruebo el avance hacia adelante
    			double newX, newY;
    			Posicion newPos = null;
				newX = miPos.getX();
				newY = miPos.getY() + 2;
				Posicion newPosDerecho =  new Posicion(newX, newY);
				double ang = miPos.angulo(newPosDerecho);
				double valDerecho = -1;
				if (newPosDerecho.distancia(posEnemigo)>distMinima && util.estaDentro(newX, newY) ) {
					valDerecho = newPosDerecho.distancia(posEnemigo);
					newX = sp.misJugadores()[N-1].getX() + 1*Math.cos(ang);
					newY = sp.misJugadores()[N-1].getY() + 1*Math.sin(ang);
					newPosDerecho =  new Posicion(newX, newY);
					if (!util.estaraDentro(newX, newY, ang)) {
						valDerecho = -1;
						newPosDerecho = null;
					}
					
				}
    			

				
    			
    			int numSep = 10;
    			int prim = 0, seg = 0;
    			if (miPos.getX()<0) {
    				prim = +1; seg = -1;
    			}
    			else {
    				prim = -1; seg = +1;
    			}
    			//System.out.println(sp.iteracion()+"PosC:"+miPos);
    			double maxIter = numSep/2; 
    			if (forzado) {
    				maxIter = numSep;
    			}
    			
    			double deltaAng = Math.PI/(double)numSep;
    			int i = 0;
    			while (i<=maxIter) {
    				newX = miPos.getX() + 2*Math.cos(Math.PI/2.0-prim*deltaAng );
    				newY = miPos.getY() + 2*Math.sin(Math.PI/2.0-prim*deltaAng );
    				Posicion newPosPrim =  new Posicion(newX, newY);
    				ang = miPos.angulo(newPosPrim);
    				double valPrim = -1;
    				if (newPosPrim.distancia(posEnemigo)>distMinima && util.estaDentro(newX, newY) ) {
    					valPrim = newPosPrim.distancia(posEnemigo);
    					newX = sp.misJugadores()[N-1].getX() + 1*Math.cos(ang);
    					newY = sp.misJugadores()[N-1].getY() + 1*Math.sin(ang);
    					newPosPrim =  new Posicion(newX, newY);
    					if (!util.estaraDentro(newX, newY, ang)) {
    						valPrim = -1;
        					prim = prim + (int)Math.round(Math.signum((double)prim));    						
    					}
    					
    				}
    				else {
    					prim = prim + (int)Math.round(Math.signum((double)prim));
    				}
    				
    				newX = miPos.getX() + 2*Math.cos(Math.PI/2.0-seg*deltaAng );
    				newY = miPos.getY() + 2*Math.sin(Math.PI/2.0-seg*deltaAng );
    				Posicion newPosSeg =  new Posicion(newX, newY);
					ang = miPos.angulo(newPosSeg);
					double valSeg = -1;
    				if (newPosSeg.distancia(posEnemigo)>distMinima && util.estaDentro(newX, newY)) {
    					valSeg = newPosSeg.distancia(posEnemigo);
    					newX = sp.misJugadores()[N-1].getX() + Math.cos(ang);
    					newY = sp.misJugadores()[N-1].getY() + Math.sin(ang);
    					newPosSeg =  new Posicion(newX, newY);
    					if (!util.estaraDentro(newX, newY, ang)) {
    						valSeg = -1;
        					seg = seg + (int)Math.round(Math.signum((double)seg));    						
    					}

    				}
    				else {
    					seg = seg + (int)Math.round(Math.signum((double)seg));
    				}
    				
    				if (valPrim!=-1 || valSeg!=-1 || ((prim==2 || seg==2) && valDerecho!=-1) ) {
    					if ((valPrim>valSeg && valPrim>valDerecho) ) {
    						newPos = newPosPrim;
    					}
    					else
       					if (valSeg>valPrim && valSeg>valDerecho) {
        						newPos = newPosSeg;
       					}
       					else
       					if (valDerecho>valPrim && valDerecho>valSeg) {
        						newPos = newPosDerecho;
       					}       						
    					
    					break;
    				}
    				
    				
    				i++;
    			}
    			
				if (sp.misJugadores()[N-1].getY()>Constantes.penalSup.getY()) {
	    			if (sp.misJugadores()[N-1].getX()<0) {
	    				newPos = new Posicion(sp.misJugadores()[N-1].getX()+1, miPos.getY());
	    			}
	    			else {
	    				newPos = new Posicion(sp.misJugadores()[N-1].getX()-1, miPos.getY());
	    			}					
				}    			
    			
    			if (newPos!=null) {
    				//System.out.println("gambeta");
    				comando[0] = new ComandoIrA(N-1, newPos);    			
				    comando[1] = new ComandoGolpearBalon(N-1);
    			}
    			
    		}
    		
    		return comando;
    	}
    	
    	
    	//-----------------------------------------------------------------------------------------------------------------
    	public Comando[] rematar() {
    		Comando[] comando = new Comando[2];
    		comando[0] = null; comando[1] = null;
    		
    		if (util.puedoRematar(N) ) {
    			
    			if (N!=1) {
    				Posicion miPos = sp.misJugadores()[N-1];
	    			double miDis = miPos.distancia(Constantes.centroArcoSup);    			
					
	    			Posicion arqueroRival = sp.rivales()[Constantes.centroArcoSup.indiceMasCercano(sp.rivales())] ;
					double distIzq = arqueroRival.getX()-Constantes.posteIzqArcoSup.getX();
					double distDer = Constantes.posteDerArcoSup.getX() - arqueroRival.getX();
					Posicion posRemate = null;
					if (distIzq<=0 || distDer<=0 || (arqueroRival.getY()<=Constantes.centroArcoSup.getY()-4 && miPos.getY()>=arqueroRival.getY())) {
						posRemate = Constantes.centroArcoSup;
					}
					else {
						if (distIzq>distDer) {
							posRemate = new Posicion((arqueroRival.getX()+Constantes.posteIzqArcoSup.getX())/2.0, Constantes.centroArcoSup.getY());
						}
						else {
							posRemate = new Posicion((arqueroRival.getX()+Constantes.posteDerArcoSup.getX())/2.0, Constantes.centroArcoSup.getY());
						}
					}

					
//	    			if ((miPos.getY()>=Constantes.centroArcoSup.getY()-8.0) && (miPos.getX()<Constantes.posteIzqArcoSup.getX() || miPos.getX()>Constantes.posteDerArcoSup.getX())) {
//    					jugadorRecibePase = Constantes.penalSup.indiceMasCercano(sp.misJugadores());
//    					cambioDireccion = true;
//        				iteracionPase = sp.iteracion();
//        				inicioPase = miPos;
//
//        				comando[0] = new ComandoGolpearBalon(N-1, Constantes.penalSup, 0.1, false);
//	    			}
	    			
					if (comando[0]==null) {
						
		    			if (miDis<MisConstantes.DISTANCIA_ARCO_REMATE_CENTRO && Math.abs(miPos.getX())>20 ) {
		    				int cercanoPuntoPenal = Constantes.penalSup.indiceMasCercano(sp.misJugadores(),N-1); 
		    				
	    					comando[0] = new ComandoGolpearBalon(N-1, sp.misJugadores()[cercanoPuntoPenal], 1, false);
		    			}
		    			else						
		    			if (miDis<MisConstantes.DISTANCIA_ARCO_REMATE_CERCA) {
	    					comando[0] = new ComandoGolpearBalon(N-1, posRemate, 1, false);
		    			}
		    			else
		    			if (miDis<MisConstantes.DISTANCIA_ARCO_REMATE_LEJOS) {		    				
		    				if (miPos.getX()<Constantes.posteIzqArcoSup.getX()) {
		    					comando[0] = new ComandoGolpearBalon(N-1, posRemate, 1, false);
		    				}
		    				else 
		    				if (Constantes.posteDerArcoSup.getX()<miPos.getX()) {
		    					comando[0] = new ComandoGolpearBalon(N-1, posRemate, 1, false);
		    				}
		    				else {
		    					comando[0] = new ComandoGolpearBalon(N-1, Constantes.centroArcoSup, 1, false);
		    				}		    				
		    			}
		    			
					}
	    			
	    			
    			}    			
    			
    		}
    		
    		return comando;
    	}    	
    	
    	
    	
       	//-----------------------------------------------------------------------------------------------------------------	
    	protected Comando[] darPase() {
    		Comando[] comando = new Comando[2];
    		comando[0] = null; comando[1] = null;
    		
    		if (util.puedoRematar(N)) {
    			Posicion miPos = sp.misJugadores()[N-1] ;
    			int numJugadorMaximo = -1;
    			Posicion pase = null;
    			
    			int numPos = 20;
    			double[] fitnessPos = new double[numPos+1];
    			Posicion[] mejoresPos = new Posicion[numPos+1];
    			
    			Arrays.fill(fitnessPos, Double.MAX_VALUE);
    			
    			double deltaAng = Math.PI/numPos;
    			Posicion posInicial = new Posicion (miPos.getX()+Constantes.getVelocidad(detalle.getJugadores()[N-1].getVelocidad()), miPos.getY());
    			for (int i=1; i<=numPos; i++) {
    				Posicion p = new Posicion(posInicial.getX(), posInicial.getY());
					double dx = posInicial.getX() - miPos.getX();
					double dy = posInicial.getY() - miPos.getY();
					             
					int it = 1;
    				while (util.estaDentro(p.getX(), p.getY()) && p.distancia(posInicial)<18.0) {
    					double miDist = p.distancia(sp.misJugadores()[p.indiceMasCercano(sp.misJugadores(),N-1)]);
    					double distEnemigo = p.distancia(sp.rivales()[p.indiceMasCercano(sp.rivales())]);
    					
    					if (miDist<distEnemigo) {
    						double fitness = 0.0;
    						for (Posicion j : sp.rivales())
    							if (j.distancia(p)<6.0) {
    								fitness++;
    							}
    						
    						fitness += p.distancia(Constantes.centroArcoSup);
    						if (miPos.getY()<-Constantes.LARGO_CAMPO/4.0) {
    							fitness +=  (Constantes.ANCHO_CAMPO/2.0-Math.abs(p.getX()));
    						}
    						
    						if (fitness<fitnessPos[i]) {
    							fitnessPos[i] = fitness;
    							mejoresPos[i] = new Posicion(p.getX(), p.getY());
    						}
    					}
//    					else {
//    						if (distEnemigo/0.6<it) {
//    							break;
//    						}
//    					}
    					
    					p = p.moverPosicion(dx, dy);
    					it++;
    				}
    				    				
    				posInicial = miPos.moverAngulo(i*deltaAng, Constantes.getVelocidad(detalle.getJugadores()[N-1].getVelocidad()));
    			}
    			
    			double min = Double.MAX_VALUE;    			
    			for (int j=0; j<=numPos; j++)  
    				if (fitnessPos[j]<min) {
    					min = fitnessPos[j];
    					pase = mejoresPos[j];
    				}
    			
    			
    			if (pase == null) {
	    			mejoresPos = new Posicion[numPos+1];    			
	    			Arrays.fill(fitnessPos, Double.MAX_VALUE);
	    			
	    			posInicial = new Posicion (miPos.getX()+Constantes.getVelocidad(detalle.getJugadores()[N-1].getVelocidad()), miPos.getY());
	    			for (int i=-1; i>=-numPos; i--) {
	    				Posicion p = new Posicion(posInicial.getX(), posInicial.getY());
						double dx = posInicial.getX() - miPos.getX();
						double dy = posInicial.getY() - miPos.getY();
						             
						int it = 1;
	    				while (util.estaDentro(p.getX(), p.getY()) && p.distancia(posInicial)<18.0) {
	    					double miDist = p.distancia(sp.misJugadores()[p.indiceMasCercano(sp.misJugadores(),N-1)]);
	    					double distEnemigo = p.distancia(sp.rivales()[p.indiceMasCercano(sp.rivales())]);
	    					
	    					if (miDist<distEnemigo) {
	    						double fitness = 0.0;
	    						for (Posicion j : sp.rivales())
	    							if (j.distancia(p)<6.0) {
	    								fitness++;
	    							}
	    						
	    						fitness += p.distancia(Constantes.centroArcoSup);
	    						if (miPos.getY()<-Constantes.LARGO_CAMPO/4.0) {
	    							fitness += (Constantes.ANCHO_CAMPO/2.0-Math.abs(p.getX()));
	    						}

	    						
	    						if (fitness<fitnessPos[numPos+i]) {
	    							fitnessPos[numPos+i] = fitness;
	    							mejoresPos[numPos+i] = new Posicion(p.getX(), p.getY());
	    						}
	    					}
	    					else {
    							break;
	    					}
	    					
	    					p = p.moverPosicion(dx, dy);
	    					it++;
	    				}
	    				    				
	    				posInicial = miPos.moverAngulo(i*deltaAng, Constantes.getVelocidad(detalle.getJugadores()[N-1].getVelocidad()));
	    			}
	    			
	    			min = Double.MAX_VALUE;    			
	    			for (int j=0; j<=numPos; j++)
	    				if (fitnessPos[j]<min) {
	    					min = fitnessPos[j];
	    					pase = mejoresPos[j];
	    				}
    			}
    			
    			
    			if (pase!=null) {
    				//System.out.println("N: " + N);
    				//System.out.println("MiPos:"+miPos);
    				//System.out.println("Pase:" + pase.distancia(miPos));
    				//System.out.println();
    				
	    			double fuerza = (miPos.distancia(pase))/15.0;
	    			if (fuerza>1.0) {
	    				fuerza = 1.0;
	    			}
	    			else
	    			if (fuerza<0.1) {
	    				fuerza = 0.1;
	    			}
	    			
	    			numJugadorMaximo = pase.indiceMasCercano(sp.misJugadores(), N-1, 0)+1;
	    			marcado = true;
	    			
    				comando[0] = new ComandoGolpearBalon(N-1, pase, fuerza, false);    		
    				cambioDireccion = true;
    				iteracionPase = sp.iteracion();
    				jugadorRecibePase = numJugadorMaximo;
    				inicioPase = sp.balon();
    			}
    			else 
    			if (N==1) {
    				comando[0] = new ComandoGolpearBalon(N-1, Constantes.centroCampoJuego, 1, true);    				
    			}
    			else {
					//System.out.println("forzado:" + miPos.distancia(sp.rivales()[miPos.indiceMasCercano(sp.rivales())] ) );					
					//comando = this.gambetear(true);    				
    			}
    			
    		}
    	
    		return comando;
    	}
    	
    	
    	
    	//-----------------------------------------------------------------------------------------------------------------	
    	private Comando[] moverse() {
    		Comando[] comando = new Comando[2];
    		comando[0] = null; comando[1] = null;
    		Posicion miPos = sp.misJugadores()[N-1] ;    		
    		Posicion balon = sp.balon();
    		
    		int masCercano = balon.indiceMasCercano(sp.misJugadores());

    		if (comando[0]==null && masCercano==(N-1) && (N!=1 || balon.getY()<-35) ) {    			
        		Posicion recibe = null;
        		Posicion p = sp.balon();
        		dx = sp.balon().getX() - balonAnt.getX();
        		dy = sp.balon().getY() - balonAnt.getY();
        		
        		double distMin = Double.MAX_VALUE;
        		for(int iter=0; iter<50; iter++) {
                    dx = dx * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
                    dy = dy * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
                    //System.out.println(iter+"->" + p.distancia(p.moverPosicion(dx, dy)));
                    
        			p = p.moverPosicion(dx, dy);        			
        			
        			double dist = p.distancia(miPos);
        			if (dist<distMin) {
        				distMin = dist;
        				recibe = p;
        			}
        		}    			
    			
    			
   		        comando[0] = new ComandoIrA(N-1, recibe);
    			
    		}
    		
    		if (comando[0]==null && N==1 && !sp.saco()) {
    			double x = balon.getX();
    			if (x<Constantes.posteIzqArcoInf.getX()) {
    				x = Constantes.posteIzqArcoInf.getX();
    			}
    			if (Constantes.posteDerArcoInf.getX()<x) {
    				x = Constantes.posteDerArcoInf.getX();
    			}    			
    			    			
    			comando[0] = new ComandoIrA(N-1, new Posicion(x,-50.5) );
    		}

 

			int indiceRivalConBalon = balon.indiceMasCercano(sp.rivales());
			Posicion rivalConBalon = sp.rivales()[indiceRivalConBalon];
    		if (comando[0]==null && N!=1 &&  (jugadorRecibePase!=N  || iteracionPase<sp.iteracion()) 
    				&& balon.distancia(rivalConBalon)<balon.distancia(sp.misJugadores()[masCercano])) {
    			Posicion masCercanoRival = sp.rivales()[ rivalConBalon.indiceMasCercano(sp.rivales(), indiceRivalConBalon) ];
    				
    			int miJugadorMasCercano = masCercanoRival.indiceMasCercano(sp.misJugadores()) + 1;
    			if (miJugadorMasCercano==N) {
	    			double x = masCercanoRival.getX();
	    			double y = masCercanoRival.getY();
	    				
	    			if (balon.getX()<x) x -= 1.5;
	    			else 
	    			if (balon.getX()>x) x += 1.5;
	    				
	    			if (balon.getY()<y) y -= 1.5;
	    			else 
	    			if (balon.getY()>y) y += 1.5;
	    				
	    			comando[0] = new ComandoIrA(N-1, new Posicion(x,y) );
    			}
    			
    		}

    		
    		if (comando[0]==null  && N!=9 && (jugadorRecibePase!=N  || iteracionPase<sp.iteracion())) {
    			
    			if (N!=1 || balon.getY()<-35) {
	    			int[] cercanos = balon.indicesMasCercanos(sp.misJugadores());
	    			
	    			Posicion p = new Posicion(balon.getX(), balon.getY()-2.5);
	    			if (cercanos[1]==N-1) {
	    				comando[0] = new ComandoIrA(N-1, p);
	    				//System.out.println("SEgundo mas cerca: " + N);
	    			}
    			}
    			
    		}
    		
    		
//    		if (comando[0]==null && N!=1 && (jugadorRecibePase!=N  || iteracionPase<sp.iteracion())) {
//    			if (sp.balon().getY()<0 && N<=4) {
//    				comando[0] = new ComandoIrA(N-1, sp.rivales()[marcasJugador[N-1]]);
//    			}
//    			
//    			if (sp.balon().getY()>Constantes.LARGO_CAMPO/4.0 && N>=8) {
//    				//comando[0] = new ComandoIrA(N-1, sp.rivales()[marcasJugador[N-1]]);
//    			}
//    				
//    		}
    	    
    		
    		
    		if (comando[0]==null && N!=1 && (jugadorRecibePase!=N  || iteracionPase<sp.iteracion())) {
    			double posYAtaqueAdelantado = Constantes.penalSup.getY()/2.0;
				double posYAtaque = 0;
				double posYDefensa = Constantes.penalInf.getY()/2.0;
				Posicion destinoAlineacion = null;
				Posicion destino = null;

				
				if (sp.balon().getY()>=posYAtaqueAdelantado) {
					destinoAlineacion = alineacionAtaqueAdelantado[N-1];
				}
				else
    			if (sp.balon().getY()>=posYAtaque) {
    				destinoAlineacion = alineacionAtaque[N-1];
    			}
    			else
        		if (sp.balon().getY()<=posYDefensa) {
        			destinoAlineacion =  alineacionDefensa[N-1];
        		}
        		else {
        			destinoAlineacion = alineacion[N-1];
        		}
    			
    			
    			Posicion rivalMasCercanoAMiPos = sp.rivales()[miPos.indiceMasCercano(sp.rivales())];
    			
    			Posicion derInf = new Posicion(destinoAlineacion.getX()+1, destinoAlineacion.getY()-1);
    			Posicion derSup = new Posicion(destinoAlineacion.getX()+1, destinoAlineacion.getY()+1);
    			Posicion izqSup = new Posicion(destinoAlineacion.getX()-1, destinoAlineacion.getY()-1);
    			Posicion izqInf = new Posicion(destinoAlineacion.getX()-1, destinoAlineacion.getY()+1);
    			
    			double distDerInf = util.distanciaPuntoALinea(miPos, derInf, rivalMasCercanoAMiPos, true);
    			double distDerSup = util.distanciaPuntoALinea(miPos, derSup, rivalMasCercanoAMiPos, true);
    			double distIzqSup = util.distanciaPuntoALinea(miPos, izqSup, rivalMasCercanoAMiPos, true);
    			double distIzqInf = util.distanciaPuntoALinea(miPos, izqInf, rivalMasCercanoAMiPos, true);
    			
    			if (distDerInf>distDerSup && distDerInf>distIzqSup && distDerInf>distIzqInf) {
    				destino = derInf;
    			}
    			else
       			if (distDerSup>distDerInf && distDerSup>distIzqSup && distDerSup>distIzqInf) {
        			destino = derSup;	
       			}
       			else
         		if (distIzqSup>distDerInf && distIzqSup>distDerSup && distIzqSup>distIzqInf) {
            		destino = izqSup;		
            	}
         		else {
         			destino = izqInf;
         		}
    			
    			
    			if (destino!=null) {
    				comando[0] = new ComandoIrA(N-1, destino);
    			}
    			
    		}
    		

    		
    		return comando;
    	}    	


    }    
}


